#ifndef _TIMER_8BIT_PWM_H_
#define _TIMER_8BIT_PWM_H_

#include <avr/io.h>
#include <avr/interrupt.h>
#include "../../../../bit/bit.h"
#include "../../../Component.h"

namespace Hardware
{
namespace Avr
{
	typedef struct TIMER_8BIT_PWM_CONFIG
	{
		unsigned char force : 1;	
		unsigned char waveform : 2;
		unsigned char compareMode : 2;
		unsigned char clockSelect : 3;
		unsigned char count : 8;
		unsigned char compare : 8;
		unsigned char compareInterrupt : 1;
		unsigned char overflowInterrupt : 1;
		
	} Timer8BitPwmConfig;

	typedef struct TIMER_8BIT_PWM_DATA
	{
	} Timer8BitPwmData;

	class Timer8BitPwm : public Component<Timer8BitPwmConfig, Timer8BitPwmData>
	{
		public :
		enum WaveFormModes
		{
			NormalMode = 0x00,
			PWM_PhaseCorrect = 0x01,
			CTC_Mode = 0x02,
			FastPWM = 0x03
		};
		enum CompareOutputMode
		{
			NormalOutputMode = 0x00,
			ReservedCompareMode = 0x01,
			ClearOnCompare = 0x02,
			SetOnCompare = 0x03
		};
		enum ClockSelectPrescalerModes
		{
			NoClockSource = 0x00,
			Prescaler1 = 0x01,
			Prescaler8 = 0x02,
			Prescaler64 = 0x03,
			Prescaler256 = 0x04,
			Prescaler1024 = 0x05,
			PrescalerExtFalling = 0x06,
			PrescalerExtRising = 0x07
		};

		Timer8BitPwm(){}
		Timer8BitPwm(Timer8BitPwmConfig c){configuration=c;}

		void config()
		{
			//set force
			TCCR0 = SetBit(TCCR0, FOC0, configuration.force);
			//set waveform
			TCCR0 = SetBit(TCCR0, WGM00, 
					GetBit(configuration.waveform,0));
			TCCR0 = SetBit(TCCR0, WGM01,
					GetBit(configuration.waveform,1));
			//set compare mode
			TCCR0 = (TCCR0 & ~(0x03 << COM00)) |
	 				(configuration.compareMode << COM00);
			//set prescaler
			TCCR0 = (TCCR0 & ~(0x07)) | configuration.clockSelect;
			//set count
			TCNT0 = configuration.count;
			//set compare
			OCR0 = configuration.compare;
			//set compare interrupt
			TIMSK = SetBit(TIMSK, OCIE0, 
						 configuration.compareInterrupt);
			//set overflow interrupt
			TIMSK = SetBit(TIMSK, TOIE0,
						 configuration.overflowInterrupt);
			
		}

	};
}}





#endif
